/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright @ Huawei Technologies Co., Ltd. 2022-2022. ALL rights reversed.
 */
#ifndef _ARM_KERNEL_LWT_H
#define _ARM_KERNEL_LWT_H

#include <asm/stacktrace.h>
#ifdef CONFIG_EULEROS_LWT

#define RET_LWT_OK		0
#define RET_LWT_ERR		-1

struct lwt_stacktrace_ops {
	int (*is_lwt_stack)(unsigned long stack);
	int (*lwt_stask_walk_all)(int (*fn)(struct stackframe *, void *), void *data);
};

/*
 * register LWT stack trace operations structure.
 *
 * @ops: pointer to LWT stack trace operations structure
 * return value: RET_LWT_OK -success, RET_LWT_ERR -failed
 */
int register_lwt_work(struct lwt_stacktrace_ops *ops);

/*
 * unregister LWT stack trace operations structure.
 *
 * return value: RET_LWT_OK -success, RET_LWT_ERR -failed
 */
void unregister_lwt_work(void);

/*
 * wapper function check if address in kernel text range.
 *
 * @addr: the address.
 * return value: RET_LWT_OK -success, RET_LWT_ERR -failed
 */
int lwt_kernel_text_address(const unsigned long addr);

extern void lwt_add_ref(void);
extern void lwt_del_ref(void);
extern bool lwt_klp_check_jump_func(void *ws_args, unsigned long pc);
extern void lwt_klp_walk_stackframe(int (*fn)(struct stackframe *, void *), void *data);
extern void save_crashing_cpu(void);
extern int klp_check_lwt_jump_func(struct stackframe *frame, void *data);
#else
static inline void lwt_klp_walk_stackframe(int (*fn)(struct stackframe *, void *), void *data) {};
static inline void save_crashing_cpu(void) {};
static inline int klp_check_lwt_jump_func(struct stackframe *frame, void *data)
{
	return 0;
}
#endif /* CONFIG_EULEROS_LWT */
#endif /* _ARM_KERNEL_LWT_H */
